// Author：时光
// 图片加载处理
// 加载完成前显示的图片
import loading_img from "@/assets/img/loading.svg";
// 出错时显示的图片
import error_img from "@/assets/img/img_error.svg";
// 预加载
document.createElement("img").src = loading_img;
document.createElement("img").src = error_img;

// 创建样式
let style = document.createElement("style");
style.type = "text/css";
style.innerHTML = `
    img[src=''],img:not([src]) {
        opacity: 0;
    }
    .img_loading {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%) scale(.6);
      width: auto !important;
      height: auto !important;
      border-radius: 6px;
      padding: 5px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      background: #ffffff;
      opacity: .6;
      max-height: 80px;
      pointer-events: none;
    }
    .img_error {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%) scale(.6);
        width: auto !important;
        height: auto !important;
        border-radius: 6px;
        padding: 5px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        background: #ffffff;
        opacity: .6;
        max-height: 60px;
        pointer-events: none;
    }
`;
document.body.appendChild(style);

// 定义自定义指令
const defineDirective = (app: any) => {
  // imgLazy为指令名称
  app.directive("imgLazy", {
    mounted(el: HTMLImageElement, bindings: any) {
      // 获取其父元素
      let parent = <HTMLImageElement>el.parentNode;
      // 记录一下父元素原本的position
      const parent_position_old = parent.style.position;
      parent.style.position = "relative !important";

      // 创建一个img标签用于loading
      const loading_img_el = document.createElement("img");
      loading_img_el.src = loading_img;
      loading_img_el.classList.add("img_loading");

      // 创建一个img标签用于error
      const error_img_el = document.createElement("img");
      error_img_el.src = error_img;
      error_img_el.classList.add("img_error");

      // 监听图片是否进入可视区
      const oberver = new IntersectionObserver(([{ isIntersecting }]) => {
        // 默认加载动画
        // 当进入可视区域时
        if (isIntersecting) {
          // 给图片的src属性赋值图片的地址
          el.src = bindings.value;

          // 记录一下img标签原本的内联display
          const display_old = el.style.display;
          // 先隐藏正常的img
          el.style.display = "none !important";
          parent?.appendChild(loading_img_el);

          // 图片成功加载后
          el.onload = () => {
            el.style.display = display_old;
            parent.style.position = parent_position_old;
            parent?.removeChild(loading_img_el);
            parent?.removeChild(error_img_el);
            el.classList.remove("img_error");
            el.onload = null;
            el.onerror = null;
          };

          // 图片加载失败时
          el.onerror = () => {
            parent?.removeChild(loading_img_el);
            parent?.appendChild(error_img_el);
            el.onload = null;
            el.onerror = null;
          };

          oberver.unobserve(el);
        } else {
          // 未进入可视区域时
        }
      });
      // 监听dom元素
      oberver.observe(el);
    },
  });
};

export default {
  install(app: any) {
    // 自定义指令
    defineDirective(app);
  },
};
